import { app, BrowserWindow, screen, protocol, dialog } from 'electron';
import * as path from 'path';
import * as fs from 'fs';
import logger from "./tools/log/log"
import { electronRouter } from './router/index';
import { createProtocol } from './tools/protocol/createProtocol'
import { runChild } from './tools/child/child';
import { checkForUpdates } from './tools/update/update';

let win: BrowserWindow = null;
const args = process.argv.slice(1);
const serve = args.some(val => val === '--serve');
//创建单例锁，禁止多开
const gotTheLock = app.requestSingleInstanceLock()
//logger.info('gotTheLock:' + gotTheLock)
//如果返回false，说明已经存在锁
if (!gotTheLock) {
  //logger.info('!gotTheLock')
  app.quit()
} else {
  //第一个实例启动，就开启了第二个实例的监听，当第二个实例启动的时候，就会被触发
  app.on('second-instance', (event, argv) => {
    //logger.info('second-instance')
    if (win) {
      if (win.isMinimized()) {
        win.restore()
      }
      if (win.isVisible()) {
        win.focus()
      } else {
        win.show()
      }
    }
  })
}

logger.info('Logger:start')

//开发环境下
if (!app.isPackaged) {
  process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
  // 禁用当前应用程序的硬件加速  不禁用提示 ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is disabled, ANGLE is
  app.disableHardwareAcceleration()
}

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{
  scheme: 'app',
  privileges: {
    supportFetchAPI: true,
    secure: true,
    standard: true,
    //bypassCSP: true,
    //corsEnabled: true,
    //stream: true
  }
}])


function createWindow(): BrowserWindow {

  const size = screen.getPrimaryDisplay().workAreaSize;

  /**
   * 开启隔离上下文 只能使用contextBridge API,判断electron环境可以从contextBridge API是否存在
   * 关闭隔离上下文 只能使用集成node进行通信，webpack.config配置需要开启config.target = 'electron-renderer'; 判断electron环境window.process是否存在
   * 最新electron推荐隔离上下使用，更安全
   */

  // Create the browser window.
  win = new BrowserWindow({
    x: 0,
    y: 0,
    width: size.width,
    height: size.height,
    webPreferences: {
      webSecurity: false,    //同源策略，API存在跨域，跨端口请求需要允许
      nodeIntegration: true, //当有此属性时, webview 中的访客页（guest page）将具有Node集成, 并且可以使用像 require 和 process 这样的node APIs 去访问低层系统资源。 Node 集成在访客页中默认是禁用的。
      allowRunningInsecureContent: false,
      contextIsolation: true, //上下文隔离是 Electron 中的一项安全措施，可确保 预加载脚本不会将拥有优先权的 Electron 或 Node.js API 泄漏到 Web 渲染器进程中的内容。 启用上下文隔离后，从预加载脚本公开的API方法是唯一通过 contextBridge API的内容。
      preload: path.join(__dirname, 'preload.js') //electron是运行时加载preload，无法使用ts
    },
  });

  if (!app.isPackaged) {
    win.webContents.openDevTools();
  }

  //初始化服务对象
  new electronRouter(win)
  //启动子进程
  runChild();
  //检查更新
  if (app.isPackaged) {
    //checkForUpdates(win);
  }

  if (serve) {
    try {
      const debug = require('electron-debug');
      debug();
      require('electron-reloader')(module);
    } catch (err){
      console.log(err);
    }
    win.loadURL('http://localhost:4200');
  } else {
    // Path when running electron executable
    let pathIndex = './index.html';
    if (fs.existsSync(path.join(__dirname, '../dist/index.html'))) {
      // Path when running electron in local folder
      pathIndex = '../dist/index.html';
    }

    //默认file协议
    //const url = new URL(path.join('file:', __dirname, pathIndex));
    //win.loadURL(url.href);

    //自定义app协议
    createProtocol('app')
    let url = path.join('app:', __dirname, pathIndex)
    win.loadURL(url);
  }

  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store window
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null;
  });

  return win;
}

try {
  // This method will be called when Electron has finished
  // initialization and is ready to create browser windows.
  // Some APIs can only be used after this event occurs.
  // Added 400 ms to fix the black background issue while using transparent window. More detais at https://github.com/electron/electron/issues/15947
  app.on('ready', () => setTimeout(createWindow, 400));

  // Quit when all windows are closed.
  app.on('window-all-closed', () => {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
      app.quit();
    }
  });

  app.on('activate', () => {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (win === null) {
      createWindow();
    }
  });

} catch (e) {
  // Catch Error
  // throw e;
}



